大佬总结链接)
核心模板1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if (nums.length == 0) return res;
Arrays.sort(nums);//排序很关键
helper(res, new ArrayList<>(), nums, 0);
return res;
}
//有些需要start,有些不需要
private void backtrack(List<List<Integer>> res, List<Integer> temp, int[] nums, int start){
if (满足条件){
res.add(new ArrayList<>(temp));
return;
}
for (int i = start; i < nums.length; i++){//构建循环
//1. 是否去重
//2. temp添加元素
//3. 递归调用,param变化
//4. temp去掉末尾元素
}
}
Subsets Problem
本题求子集,元素数量会变化,所以没有判断条件直接res.add()
LeetCode 78. Subsets
- 循环start递增
1
2
3
4
5
6
7
8private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
- 循环start递增
- 跳过重复
1
2
3
4
5
6
7
8
9private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
- 排列,需要调换顺序,所以从0开始
- 去重
1
2
3
4
5
6
7
8
9
10
11
12private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
} else{
for(int i = 0; i < nums.length; i++){
if(tempList.contains(nums[i])) continue; // element already exists, skip
tempList.add(nums[i]);
backtrack(list, tempList, nums);
tempList.remove(tempList.size() - 1);
}
}
}
Permutations II (contains duplicates)
- 去重,很关键
- 用used数组辅助
1
2
3
4
5
6
7
8
9
10
11
12
13
14private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
} else{
for(int i = 0; i < nums.length; i++){
if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue;
used[i] = true;
tempList.add(nums[i]);
backtrack(list, tempList, nums, used);
used[i] = false;
tempList.remove(tempList.size() - 1);
}
}
}
Combination Sum1
2
3
4
5
6
7
8
9
10
11private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){
if(remain < 0) return;
else if(remain == 0) list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can reuse same elements
tempList.remove(tempList.size() - 1);
}
}
}
Combination Sum II (can’t reuse same element)
1 | private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ |
Palindrome Partitioning1
2
3
4
5
6
7
8
9
10
11
12
13public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){
if(start == s.length())
list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < s.length(); i++){
if(isPalindrome(s, start, i)){
tempList.add(s.substring(start, i + 1));
backtrack(list, tempList, s, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
}